﻿using Modbus.Extensions.Enron;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NModbus4_Library_Demo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnGet_Click(object sender, EventArgs e)
        {
            //开了一个新线程
            Task.Run(() =>
            {
                //这里死循环是为了演示,会导致程序无法退出  窗口关闭结束所有子线程
                while (true)
                {
                    //到从站获取湿度数据
                    //1.从站的通信方式:串口
                    //2.从站支持的通信协议
                    //3.设备的存储点位
                    using (SerialPort serialPort = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One))
                    {
                        serialPort.Open();
                        Modbus.Device.ModbusSerialMaster master = Modbus.Device.ModbusSerialMaster.CreateRtu(serialPort);

                        //读保持寄存器
                        //参数1:从站地址,这里读的是从站1(用字节的16进制表示:0x01),也可以用整数1: master.ReadHoldingRegisters(1, 1, 1);
                        //参数2:起始地址
                        //参数3:读多少个点位
                        //读取1号从站中的1号保持型寄存器
                        ushort[] datas = master.ReadHoldingRegisters(0x01, 1, 1);

                        bool [] coil=master.ReadCoils(1,0,1);

                        if (datas != null && datas.Length > 0)
                        {
                            this.Invoke(new Action(() =>
                            {
                                lblhumidity.Text = datas[0].ToString();
                                label2.Text = coil[0].ToString();
                            }));
                        }
                    }

                    Task.Delay(200);
                }
            });


        }

        //485通信 半双工: 通信链路中,一个时间只允许一个报文传输(一直读的时候然后写(同时读写)可能会出现问题)
        //解决:读写队列:两个队列读队列和写队列,假设以写为主,如果写队列里有直接写,如果写队列里没有再读取读队列
        private void btnWrite_Click(object sender, EventArgs e)
        {
            using (SerialPort serialPort = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One))
            {
                serialPort.Open();
                Modbus.Device.ModbusSerialMaster master = Modbus.Device.ModbusSerialMaster.CreateRtu(serialPort);

                //写入保持寄存器
                master.WriteSingleRegister(1, 2, ushort.Parse(txtpressure.Text));

                //写入输入线圈
                master.WriteSingleCoil(1, 0, true);
            }
        }
    }
}
